home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 002 / interface2 / !DOCS / DEMO / C / WIN < prev   
Encoding:
Text File  |  1991-01-01  |  7.5 KB  |  336 lines

  1. /* Title: -> c.win
  2.  * Purpose: central control of window sytem events.
  3.  *
  4.  */
  5.  
  6. #define BOOL int
  7. #define TRUE 1
  8. #define FALSE 0
  9.  
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "trace.h"
  15. #include "os.h"
  16. #include "wimp.h"
  17. #include "werr.h"
  18. #include "wimpt.h"
  19. #include "event.h"
  20. #include "msgs.h"
  21.  
  22. #include "win.h"
  23.  
  24. /* -------- Keeping Track of All Windows. -------- */
  25.  
  26. typedef struct {
  27.   wimp_w w;
  28.   win_event_handler proc;
  29.   void *handle;
  30.   void *menuh;
  31. } win__str;
  32.  
  33. #define MAXWINDOWS 65
  34. #define DUD (-1)
  35.  
  36. static win__str win__allwindows[MAXWINDOWS];
  37. static int win__lim = 0; /* first unused index of win__allwindows */
  38.  
  39. void win__register(wimp_w w, win_event_handler proc, void *handle)
  40. {
  41.   int i;
  42.   for (i=0;; i++) {
  43.     if (i == MAXWINDOWS) {
  44.       werr(1, msgs_lookup("win1:Too many windows.\n"));
  45.     };
  46.     if (i == win__lim) {win__lim++; break;};
  47.     if (win__allwindows[i].w == w) {break;}; 
  48.     if (win__allwindows[i].w == DUD) {break;};
  49.   }
  50.   win__allwindows[i].w = w;
  51.   win__allwindows[i].proc = proc;
  52.   win__allwindows[i].handle = handle;
  53.   win__allwindows[i].menuh = 0;
  54. }
  55.  
  56. void win__discard(wimp_w w)
  57. {
  58.   int i;
  59.   for (i=0; i<win__lim; i++) {
  60.     if (win__allwindows[i].w == w) {
  61.       win__allwindows[i].w = DUD;
  62.       break;
  63.     };
  64.   }
  65.   while (win__lim > 0 && win__allwindows[win__lim-1].w == DUD) {
  66.     /* decrease the limit if you can. */
  67.     win__lim--;
  68.   };
  69. }
  70.  
  71. win__str *win__find(wimp_w w)
  72. {
  73.   int i;
  74.   for (i=0; i<win__lim; i++) {
  75.     if (win__allwindows[i].w == w) {
  76.       return(&win__allwindows[i]);
  77.     };
  78.   };
  79.   return(0);
  80. }
  81.  
  82. /* -------- Claiming Events. -------- */
  83.  
  84. void win_register_event_handler(
  85.   wimp_w w, win_event_handler proc, void *handle)
  86. {
  87.   if (proc == 0) {
  88.     win__discard(w);
  89.   } else {
  90.     win__register(w, proc, handle);
  91.   };
  92. }
  93.  
  94. typedef struct unknown_previewer
  95. {
  96.  struct unknown_previewer *link ;
  97.  win_unknown_event_processor proc ;
  98.  void *handle ;
  99. } unknown_previewer ;
  100.  
  101. static wimp_w win__idle = DUD;
  102. #define win__unknown_flag (('U'<<24)+('N'<<16)+('K'<<8)+'N')
  103.  
  104. static wimp_w win__unknown = DUD;
  105. static unknown_previewer *win__unknown_previewer_list = 0 ;
  106.  
  107. void win_claim_idle_events(wimp_w w)
  108. {
  109.   tracef1("idle events -> %d\n",w) ;
  110.   win__idle = w; 
  111. }
  112.  
  113. wimp_w win_idle_event_claimer(void)
  114. {
  115.   return(win__idle);
  116. }
  117.  
  118. void win_claim_unknown_events(wimp_w w)
  119. {
  120.   win__unknown = w;
  121. }
  122.  
  123. wimp_w win_unknown_event_claimer(void)
  124. {
  125.   return win__unknown;
  126. }
  127.  
  128. void win_add_unknown_event_processor(win_unknown_event_processor p,
  129.                                      void *h)
  130. {
  131.  unknown_previewer *block = malloc(sizeof(unknown_previewer)) ;
  132.  if (block != 0)
  133.  {
  134.   block->link = win__unknown_previewer_list ;
  135.   block->proc = p ;
  136.   block->handle = h ;
  137.   win__unknown_previewer_list = block ;
  138.  }
  139. }
  140.  
  141. void win_remove_unknown_event_processor(win_unknown_event_processor p,
  142.                                         void *h)
  143. {
  144.  unknown_previewer *block ;
  145.  for (block = (unknown_previewer *) &win__unknown_previewer_list ;
  146.       block != 0 && block->link->proc != p && block->link->handle != h ;
  147.       block = block->link) ;
  148.  if (block != 0)
  149.  {
  150.   unknown_previewer *b2 = block->link ;
  151.   block->link = b2->link ;
  152.   free(b2) ;
  153.  }
  154. }
  155.  
  156. /* -------- Menus. -------- */
  157.  
  158. void win_setmenuh(wimp_w w, void *handle)
  159. {
  160.   win__str *p = win__find(w);
  161.   if (p != 0) {p->menuh = handle;};
  162. }
  163.  
  164. void *win_getmenuh(wimp_w w) /* 0 if not set */
  165. {
  166.   win__str *p = win__find(w);
  167.   return(p==0 ? 0 : p->menuh);
  168. }
  169.  
  170. /* -------- Processing Events. -------- */
  171.  
  172. BOOL win_processevent(wimp_eventstr *e)
  173. {
  174.   wimp_w w;
  175.   win__str *p;
  176.   tracef1("win_processevent %i.\n", e->e);
  177.   switch (e->e) {
  178.   case wimp_ENULL:
  179.     w = win__idle;
  180.     break;
  181.   case wimp_EUSERDRAG:
  182.     w = win__unknown_flag ;
  183.     break;
  184.   case wimp_EREDRAW: 
  185.       {
  186.           BOOL redraw;
  187.           wimp_redrawstr redraw_box;
  188.           
  189.           redraw_box.w = e->data.o.w;
  190.           wimpt_noerr (wimp_redraw_wind (&redraw_box, &redraw));
  191.           
  192.           while (redraw)
  193.           {
  194.                wimpt_complain (wimp_borderwindow (redraw_box));
  195.                wimp_get_rectangle (&redraw_box, &redraw);
  196.           }
  197.       }
  198.       w = e->data.o.w;
  199.       break;
  200.   case wimp_ECLOSE: case wimp_EOPEN:
  201.   case wimp_EPTRLEAVE: case wimp_EPTRENTER: case wimp_EKEY:
  202.   case wimp_ESCROLL:
  203.     w = e->data.o.w;
  204.     break;
  205.   case wimp_EBUT:
  206.     w = e->data.but.m.w;
  207.     if (w <= (wimp_w) -1) w = win_ICONBAR;
  208.     break;
  209.   case wimp_ESEND:
  210.   case wimp_ESENDWANTACK:
  211.     switch (e->data.msg.hdr.action) {
  212.     case wimp_MCLOSEDOWN:
  213.       tracef0("closedown message\n");
  214.       exit(0);
  215.     case wimp_MDATALOAD:
  216.     case wimp_MDATASAVE:
  217.       tracef1("data %s message arriving.\n",
  218.              (int) (e->data.msg.hdr.action==wimp_MDATASAVE ? "save" : "load"));
  219.       if (e->data.msg.data.dataload.w < 0)
  220.       {
  221.         tracef0("data message to the icon bar.\n");
  222.         w = win_ICONBARLOAD ;
  223.       } else {
  224.         w = e->data.msg.data.dataload.w;
  225.       };
  226.       break;
  227.     case wimp_MHELPREQUEST:
  228.       tracef1("help request for window %i.\n", e->data.msg.data.helprequest.m.w);
  229.       w = e->data.msg.data.helprequest.m.w;
  230.       if (w < 0) w = win_ICONBARLOAD;
  231.       break;
  232.     default:
  233.       tracef1("unknown message type %i arriving.\n", e->data.msg.hdr.action);
  234.       w = win__unknown_flag;
  235.       if (w < 0) w = win_ICONBARLOAD;
  236.     };
  237.     break;
  238.   default:
  239.     w = win__unknown_flag;
  240.   };
  241.  
  242.   if (w==win__unknown_flag || win__find(w) == 0)
  243.   {
  244.    unknown_previewer *pr ;
  245.    for (pr = win__unknown_previewer_list; pr != 0; pr = pr->link)
  246.    {
  247.     if (pr->proc(e, pr->handle)) return TRUE ;
  248.    }
  249.    w = win__unknown ;
  250.   }
  251.  
  252.   p = (w == DUD ? 0 : win__find(w));
  253.   if (p != 0) {
  254.     p->proc(e, p->handle);
  255.     return TRUE;
  256.   } else {
  257.     return FALSE;
  258.   };
  259. }
  260.  
  261. /* -------- Termination. -------- */
  262.  
  263. static int win__active = 0;
  264.  
  265. void win_activeinc(void)
  266. {
  267.   win__active++;
  268. }
  269.  
  270. void win_activedec(void)
  271. {
  272.   win__active--;
  273. }
  274.  
  275. int win_activeno(void)
  276. {
  277.   return win__active;
  278. }
  279.  
  280. /* -------- Giving away the caret. -------- */
  281.  
  282. void win_give_away_caret(void)
  283. {
  284.   int i;
  285.   for (i=0; i<win__lim; i++) {
  286.     if (win__allwindows[i].w != DUD) { /* found a window */
  287.       wimp_wstate s;
  288.       wimp_eventstr e;
  289.       tracef1("get state of window %i.", win__allwindows[i].w);
  290.       (void) wimp_get_wind_state(win__allwindows[i].w, &s);
  291.       tracef2("behind=%i flags=%i.\n", s.o.behind, s.flags);
  292.       if (s.o.behind == DUD && (s.flags & wimp_WOPEN) != 0) {
  293.         /* w is the top window */
  294.         /* if it wants the caret, it will grab it. */
  295.         tracef0("Opening it.\n");
  296.         e.e = wimp_EOPEN;
  297.         e.data.o = s.o;
  298.         wimpt_fake_event(&e);
  299.         break;
  300.       };
  301.     };
  302.   };
  303. }
  304.  
  305. /* ----------- setting a window title ------------ */
  306.  
  307. void win_settitle(wimp_w w, char *newtitle)
  308. {
  309.   wimp_redrawstr r;
  310.   wimp_winfo *winfo;
  311.  
  312.   if((winfo = malloc(sizeof(wimp_wind) + 200*sizeof(wimp_icon))) == 0)
  313.     werr(TRUE, msgs_lookup("win2:Not enough memory to change window title -- increase wimpslot"));
  314.  
  315. tracef1("New title is %s\n", (int)newtitle);
  316.   /* --- get the window's details --- */
  317.     winfo->w = w;
  318.     wimpt_noerr(wimp_get_wind_info(winfo));
  319.  
  320.   /* --- put the new title string in the title icon's buffer --- */
  321. tracef1("Lib buffer is at %d\n", (int)winfo->info.title.indirecttext.buffer);
  322.     strcpy(winfo->info.title.indirecttext.buffer, newtitle);
  323.  
  324.   /* --- invalidate the title bar in absolute coords --- */
  325.     r.w = (wimp_w) -1;    /* absolute screen coords */
  326.     r.box = winfo->info.box;
  327.     r.box.y1 += 36;            /* yuk - tweaky */
  328.     r.box.y0 = r.box.y1 - 36;
  329.     wimpt_noerr(wimp_force_redraw(&r));
  330.  
  331.   /* --- free space used to window info --- */
  332.     free(winfo);
  333. }
  334.  
  335. /* end */
  336.